package com.regent.central.bill.service.bean.mrp;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.regent.central.bill.common.ActionType;
import com.regent.central.bill.common.BillType;
import com.regent.central.bill.common.DateUtil;
import com.regent.central.bill.common.RemittanceType;
import com.regent.central.bill.core.Remittance;
import com.regent.central.bill.core.mrp.ActionMaterialReturn;
import com.regent.central.bill.core.mrp.BillMaterialReturn;
import com.regent.central.bill.core.mrp.BillMaterialReturnActions;
import com.regent.central.bill.repository.RemittanceMapper;
import com.regent.central.bill.repository.mrp.ActionMaterialReturnMapper;
import com.regent.central.bill.repository.mrp.BillMaterialReturnActionsMapper;
import com.regent.central.bill.repository.mrp.BillMaterialReturnMapper;
import com.regent.central.bill.repository.mrp.dto.billReturn.BillMaterialReturnPageDTO;
import com.regent.central.bill.repository.mrp.dto.billReturn.BillMaterialReturnPageParam;
import com.regent.central.bill.repository.mrp.dto.billReturn.BillReturnUndoResult;
import com.regent.central.bill.repository.mrp.dto.billReturn.collect.BillMaterialReturnCollectAddDTO;
import com.regent.central.bill.repository.mrp.dto.billReturn.create.BillMaterialReturnAddDTO;
import com.regent.central.bill.repository.mrp.dto.billReturn.detail.*;
import com.regent.central.bill.repository.page.Pagination;
import com.regent.central.bill.service.RemittanceService;
import com.regent.central.bill.service.mrp.BillMaterialReturnService;
import com.regent.central.infrastructure.common.Uid;
import com.regent.central.infrastructure.service.bean.DomainServiceBean;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

@Service
public class BillMaterialReturnServiceBean extends DomainServiceBean<BillMaterialReturnMapper, BillMaterialReturn> implements BillMaterialReturnService {

    @Resource
    private BillMaterialReturnMapper billMaterialReturnMapper;

    @Resource
    private ActionMaterialReturnMapper actionMaterialReturnMapper;

    @Resource
    private BillMaterialReturnActionsMapper billMaterialReturnActionsMapper;

    @Resource
    private RemittanceMapper remittanceMapper;

    @Resource
    private RemittanceService remittanceService;

    @Override
    @Transactional(readOnly = false)
    public void create(BillMaterialReturnAddDTO dto) {
        BillMaterialReturn billReturn = new BillMaterialReturn();
        //必填的
        String billReturnId = Uid.random();
        billReturn.setId(billReturnId);
        billReturn.setBossUnitId(dto.getBossUnitId());
        billReturn.setUnitId(dto.getUnitId());
        billReturn.setCreatorId(dto.getCreatorId());
        billReturn.setCreatorName(dto.getCreatorName());
        //退料日期，没有的话就取当前时间
        Date dateReturn = dto.getDateReturn();
        billReturn.setDateReturn(dateReturn == null ? new Date() : DateUtil.merge(dateReturn, new Date()));
        //退料单号，如果没有的话就按规则生产
        String billReturnNo = dto.getOrderNo();
        if (StringUtils.isBlank(billReturnNo)) {
            billReturnNo = getBillReturnNo(dto.getUnitId());
        }
        billReturn.setOrderNo(billReturnNo);
        billReturn.setReturnStroehouseId(dto.getStorehouseId());
        billReturn.setSupplierId(dto.getSupplierId());

        //选填的
        billReturn.setRemark(dto.getRemark());
        billReturn.setAmountRefund(dto.getAmountRefund());

        //仓库操作id
        billReturn.setStockChangeId(dto.getStockChangeId());

        //保存退料单信息
        billMaterialReturnMapper.insertSelective(billReturn);

        //保存退料单的物料信息
        for (BillMaterialReturnAddDTO.ReturnAddMaterialsSkuDTO sku : dto.getMaterialsSkus()) {

            //
            String materialReturnId = Uid.random();
            String actionId = Uid.random();

            ActionMaterialReturn materialReturn = new ActionMaterialReturn();
            materialReturn.setId(materialReturnId);
            materialReturn.setCommonMaterialsId(sku.getMaterialsId());
            materialReturn.setBillMaterialActionId(actionId);
            materialReturn.setActionMaterialArriveId(sku.getBillMaterialArriveId());
            materialReturn.setCommonMaterialsNo(sku.getMaterialsNo());
            materialReturn.setCommonMaterialsSkuId(sku.getMaterialsSkuId());
            materialReturn.setFacMissionId(sku.getFacMissionId());
            materialReturn.setPriceUnit(sku.getPriceUnit());
            materialReturn.setQuantity(sku.getQuantity());
            materialReturn.setStyleNo(sku.getStyleNo());
            materialReturn.setType(sku.getType());
            BigDecimal priceTotal = sku.getPriceUnit().multiply(sku.getQuantity());
            materialReturn.setPriceTotal(priceTotal);
            actionMaterialReturnMapper.insertSelective(materialReturn);

            //物料退料的动作保存
            BillMaterialReturnActions action = new BillMaterialReturnActions();
            action.setId(actionId);
            action.setActionType(ActionType.MATERIAL_RETURN.name());
            action.setActionId(materialReturnId);
            action.setCentralBillMaterialReturnId(billReturnId);

            billMaterialReturnActionsMapper.insertSelective(action);

        }

    }

    @Override
    public BillMaterialReturnDetailDTO detail(String billMaterialReturnId) {
        BillMaterialReturnDetailDTO billMaterialReturnDetailDTO = new BillMaterialReturnDetailDTO();

        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat formatAll = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        List<ReturnDetailSkuQTO> skus = billMaterialReturnMapper.listReturnActionDetail(billMaterialReturnId);
        List<ActionMaterialReturnCollectQTO> collectList = billMaterialReturnMapper.listReturnActionCollect(billMaterialReturnId);
        List<ActionMaterialReturnCollectDTO> collects = new ArrayList<>();
        BigDecimal amountCollectTotal = BigDecimal.ZERO;
        for (ActionMaterialReturnCollectQTO qto : collectList) {
            ActionMaterialReturnCollectDTO dto = new ActionMaterialReturnCollectDTO();
            BeanUtils.copyProperties(qto, dto);
            String dateCollect = format.format(qto.getDateCollect());
            String dateCreate = formatAll.format(qto.getDateCreate());
            dto.setDateCollect(dateCollect);
            dto.setDateCreate(dateCreate);
            collects.add(dto);
            amountCollectTotal = amountCollectTotal.add(qto.getCollectTotal());
        }

        List<ReturnDetailSkuDTO> returnSkus = new ArrayList<>();
        Set<String> skuIds = new HashSet<>();
        BigDecimal amountTotal = BigDecimal.ZERO;
        int quantitySku = skus.size();
        for (ReturnDetailSkuQTO returnDetailSkuQTO : skus) {
            skuIds.add(returnDetailSkuQTO.getMaterialSkuId());
            amountTotal = amountTotal.add(returnDetailSkuQTO.getReturnPriceTotal());

            //赋值
            ReturnDetailSkuDTO sku = new ReturnDetailSkuDTO();
            BeanUtils.copyProperties(returnDetailSkuQTO, sku);
            returnSkus.add(sku);
            Date dateArrive = returnDetailSkuQTO.getDateArrive();
            Date datePurchase = returnDetailSkuQTO.getDatePurchase();

            //日期
            if (dateArrive != null) {
                sku.setDateArrive(format.format(dateArrive));
            }
            if (datePurchase != null) {
                sku.setDatePurchase(format.format(datePurchase));
            }

        }
        //获取退料单信息
        if (quantitySku > 0) {
            ReturnDetailSkuQTO qto = skus.get(0);
            billMaterialReturnDetailDTO.setBillReturnId(qto.getBillReturnId());
            billMaterialReturnDetailDTO.setBillReturnNo(qto.getBillReturnNo());
            billMaterialReturnDetailDTO.setSupplierId(qto.getSupplierId());
            billMaterialReturnDetailDTO.setStorehouseId(qto.getStorehouseId());
            billMaterialReturnDetailDTO.setDateReturn(format.format(qto.getDateReturn()));
            billMaterialReturnDetailDTO.setCreatorId(qto.getCreatorId());
            billMaterialReturnDetailDTO.setCreatorName(qto.getCreatorName());
            billMaterialReturnDetailDTO.setRemark(qto.getRemark());
            billMaterialReturnDetailDTO.setStockChangeId(qto.getStockChangeId());
            billMaterialReturnDetailDTO.setCancel(qto.isCancel());
        }

        billMaterialReturnDetailDTO.setAmountCollectTotal(amountCollectTotal);
        billMaterialReturnDetailDTO.setAmountTotal(amountTotal);
        billMaterialReturnDetailDTO.setQuantitySku(skuIds.size());
        billMaterialReturnDetailDTO.setSkus(returnSkus);
        billMaterialReturnDetailDTO.setCollects(collects);

        return billMaterialReturnDetailDTO;
    }

    @Transactional
    @Override
    public void createCollectMoney(BillMaterialReturnCollectAddDTO collectAdd) {

        Remittance remittance = new Remittance();
        remittance.setId(Uid.random());
        remittance.setAmount(collectAdd.getCollectTotal());
        remittance.setBossUnitId(collectAdd.getBossUnitId());
        remittance.setOperatorId(collectAdd.getCreatorId());
        remittance.setSource(BillType.MATERIAL_RETURN);
        remittance.setSupplierId(collectAdd.getSupplierId());
        remittance.setType(RemittanceType.RECEIPT_REFUND);
        remittance.setUnitId(collectAdd.getUnitId());
        remittance.setUserCreated(collectAdd.getUpdaterId());
        remittance.setDateOperated(collectAdd.getDateCollect());
        remittanceMapper.insertSelective(remittance);

        String billReturnId = collectAdd.getBillReturnId();
        // 建立付款和采购单的关系
        BillMaterialReturnActions billMaterialReturnActions = new BillMaterialReturnActions();
        billMaterialReturnActions.setId(Uid.random());
        billMaterialReturnActions.setActionType(ActionType.REMITTANCE.name());
        billMaterialReturnActions.setCentralBillMaterialReturnId(billReturnId);
        billMaterialReturnActions.setActionId(remittance.getId());
        billMaterialReturnActionsMapper.insertSelective(billMaterialReturnActions);
    }

    private String getBillReturnNo(String unitId) {
        LocalDate now = LocalDate.now();
        String startDate = now.toString() + " 00:00:00";
        String endDate = now.toString() + " 23:59:59";
        LocalDateTime dateStart = LocalDateTime.parse(startDate, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        LocalDateTime dateEnd = LocalDateTime.parse(endDate, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        int count = billMaterialReturnMapper.countBillReturnByUnitId(unitId, dateStart, dateEnd);

        count = count + 1;
        String yearStr = now.getYear() + "";
        String year = yearStr.substring(2);
        String monthStr = now.getMonthValue() + "";
        String month = monthStr.length() <= 1 ? "0" + monthStr : monthStr;
        String dayOfMonthStr = now.getDayOfMonth() + "";
        String dayOfMonth = dayOfMonthStr.length() <= 1 ? "0" + dayOfMonthStr : dayOfMonthStr;

        String purchaseCount = count < 10 ? "00" + count : (count < 100 ? "0" + count : count + "");
        return "TL" + year + month + dayOfMonth + purchaseCount;

    }

    @Transactional
    @Override
    public BillReturnUndoResult undo(String billMaterialReturnId, String userId) {
        BillReturnUndoResult result = new BillReturnUndoResult();
        // 撤销退料单
        int effectCountBill = billMaterialReturnMapper.undoBill(billMaterialReturnId);
        if (effectCountBill <= 0) {
            result.setSuccess(false);
            return result;
        }
        // 撤销退料动作
        billMaterialReturnMapper.undoReturnAction(billMaterialReturnId);

        // 撤销退料单关联的流水
        List<String> remittanceIds = billMaterialReturnMapper.listRemittanceId(billMaterialReturnId);
        if (remittanceIds != null && remittanceIds.size() > 0) {
            for (String remittanceId : remittanceIds) {
                remittanceService.cancel(remittanceId, userId);
            }
        }

        String stockChangeId = billMaterialReturnMapper.getStockChangeId(billMaterialReturnId);
        result.setSuccess(true);
        result.setStockChangeId(stockChangeId);
        return result;
    }

    @Override
    public BillMaterialReturnPageDTO findPage(BillMaterialReturnPageParam param) {
        int pageNum = param.getPageNum() <= 0 ? 1 : param.getPageNum();
        int pageSize = param.getPageSize() <= 0 ? 20 : param.getPageSize();
        // 分页查询退料单
        Page<String> page = PageHelper.startPage(pageNum, pageSize);
        BillMaterialReturnPageDTO pageDTO = new BillMaterialReturnPageDTO();
        List<String> ids = billMaterialReturnMapper.findIdsForPage(param);
        List<ReturnDetailsSkuDTO> returnDetailSkuQTOS = new ArrayList<ReturnDetailsSkuDTO>();
        if (page.size() > 0) {
            returnDetailSkuQTOS = billMaterialReturnMapper.listReturnActionDetailByIds(ids);
        }

        Pagination<ReturnDetailSkuQTO> pagination = new Pagination<>();
        pagination.setPageSize(pageSize);
        pagination.setPageNum(pageNum);
        pagination.setTotal((int) page.getTotal());
        pageDTO.setList(returnDetailSkuQTOS);
        pageDTO.setPagination(pagination);
        return pageDTO;
    }

    public List<ReturnDetailsSkuDTO> returnExcel(BillMaterialReturnPageParam param) {
        List<ReturnDetailsSkuDTO> returnDetailSkuQTOS = billMaterialReturnMapper.returnExcel(param);
        return returnDetailSkuQTOS;
    }
}
